#include "StdAfx.h"
#include "utility.h"
#include "mylog.h"

#include <ThostFtdcTraderApi.h>
#include "datastructio.h"
#include "BaseTradeSpi.h"
#include "tradedata.h"


namespace CTPTDIF {

CTradeData::CTradeData()
	: m_pInstruments(0)
	, m_nInstruments(0)
	, m_pOrders(0)
	, m_pTrades(0)
	, m_nOrders(0)
	, m_nTrades(0)
{
}

CTradeData::~CTradeData()
{
	if (m_pTrades)
		delete m_pTrades;
	if (m_pOrders)
		delete m_pOrders;
	if (m_pInstruments)
		delete m_pInstruments;
	m_vctInsPos.clear();
	m_vctTrdPos.clear();
}

int CTradeData::GetTradePositionByIndex(int n, TRADE_POSITION& tp)
{
	if ((n < 1) || ((unsigned int)n > m_vctTrdPos.size()))
		return -1;
	tp = m_vctTrdPos[n - 1];
	return (0);
}

int CTradeData::GetInstrPositionByIndex(int n, INSTMNT_POSITION& ip)
{ 
	if ((n < 1) || ((unsigned int)n > m_vctInsPos.size()))
		return -1;

	ip = m_vctInsPos[n - 1];

	return (0);
}

ORDER * CTradeData::FindOrder(int nFrontID, int nSessionID, const char * strOrderRef, int * nIndex)
{
//	CriticalLock::Scoped lock(m_mtxOrder);

	ORDER * p = m_pOrders;
	for (int i = 0; i < m_nOrders; i++, p++)
		////SEAN SEAN SEAN, i think the front id is a constant
		////if (p->FrontID == nFrontID) && (p->SessionID == nSessionID)
		if ((p->SessionID == nSessionID) && (!strcmp(p->OrderRef, strOrderRef))) {
			*nIndex = i;
			return p;
		}

	return NULL;
}

ORDER * CTradeData::FindOrder(const char * OrderSysId, int * nIndex)
{
//	CriticalLock::Scoped lock(m_mtxOrder);

	ORDER * p = m_pOrders;
	for (int i = 0; i < m_nOrders; i++, p++)
		if (!strcmp(p->OrderSysID, OrderSysId)) {
			*nIndex = i;
			return p;
		}

	return NULL;
}

int CTradeData::IsSameOrderStatus(ORDER * o1, ORDER * o2)
{
//	CriticalLock::Scoped lock(m_mtxOrder);

	if ((o1->OrderStatus == o2->OrderStatus) && (!strcmp(o1->OrderSysID, o2->OrderSysID)))
		return (1);
	else
		return (0);
}


INSTMNT_POSITION * CTradeData::FindInsPos(const char * Instrument, char cDirection, int * nIndex)
{
	CriticalLock::Scoped l(m_mtxInstrPos);

	*nIndex = 0;
	InstrPositions::iterator Iter = m_vctInsPos.begin();
	for (; Iter != m_vctInsPos.end(); Iter++) {
		if ((!strcmp(Instrument, Iter->m_strInstrumentID)) && (Iter->m_cDirection == cDirection))
			return &(*Iter);
		*nIndex++;
	}
	return NULL;
}

TRADE_POSITION * CTradeData::FindOpenPos(const char * tradeid)
{
	//CriticalLock::Scoped l(m_mtxTradePos);

	TradePositions::iterator Iter = m_vctTrdPos.begin();
	for (; Iter != m_vctTrdPos.end(); Iter++) {
		if (!strcmp(tradeid, Iter->m_strTradeID))
			return &(*Iter);
	}
	return NULL;
}

ORDER * CTradeData::AddOrder(ORDER * order)
{
//	CriticalLock::Scoped lock(m_mtxOrder);

	memcpy(m_pOrders + m_nOrders, order, sizeof(ORDER));
	return m_pOrders + m_nOrders++;
}

void CTradeData::UpdateOrderStatus(ORDER * OldOrder, ORDER * NewOrder)
{
//	CriticalLock::Scoped lock(m_mtxOrder);

	memcpy(OldOrder, NewOrder, sizeof(ORDER));
}

} //namespace CTPTDIF